#include "cDate_t.h"

char* cDate_t::dayofweek[] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char* cDate_t::monthNames[] = { "January", "February", "March", "April", "May", "Jun", "July", "August", "September", "October", "November", "December" };

void cDate_t::setCurrentDate() 
{
	time_t time_t_Now = time(NULL);
	struct tm *tm_Now;
	tm_Now = localtime(&time_t_Now);
	setDate(tm_Now->tm_mday, tm_Now->tm_mon+1, tm_Now->tm_year+1900);
}


bool cDate_t::isYearLeap() const
{
	return (_year %4 == 0);
}


cDate_t::cDate_t()
{
	setCurrentDate();
	setPrintFormat(1);
}


cDate_t::cDate_t(const cDate_t &d) 
{
	_day = d.getDay();
	_month = d.getMonth();
	_year = d.getYear();
	_printFormat = d.getPrintFormat();
}

cDate_t::cDate_t(const int &day, const int &month, const int &year)
{
	if (!legalDate(day, month, year)) {
		setCurrentDate();
	}
	else 
	{
		_day = day;
		_month = month;
		_year = year;
	}
	setPrintFormat(1);
}


int cDate_t::getPrintFormat() const
{
	return _printFormat;
}

void cDate_t::fillStruct_tm(struct tm &tm_Temp, const int& day,const int& month,const int& year) 
{
	tm_Temp.tm_mday = day;
	tm_Temp.tm_mon = month - 1;
	tm_Temp.tm_year = year - 1900;
	tm_Temp.tm_hour = 0; tm_Temp.tm_min = 0; tm_Temp.tm_sec = 0;
	tm_Temp.tm_isdst = -1;
}

void cDate_t::fillStruct_tm(struct tm &tm_Temp) const
{
	tm_Temp.tm_mday = _day;
	tm_Temp.tm_mon = _month - 1;
	tm_Temp.tm_year = _year - 1900;
	tm_Temp.tm_hour = 0; tm_Temp.tm_min = 0; tm_Temp.tm_sec = 0;
	tm_Temp.tm_isdst = -1;
	mktime(&tm_Temp);
}

int cDate_t::getDayOfYear() const {
	struct tm tm_Temp;
	fillStruct_tm(tm_Temp);
	return tm_Temp.tm_yday;
}

bool cDate_t::legalDate(const int& day,const int& month,const int& year)
{
	struct tm tm_Temp;
	fillStruct_tm(tm_Temp, day, month, year);
	struct tm tm_TempCopy = tm_Temp;
	time_t time_t_temp = mktime (&tm_Temp);
	return (time_t_temp != -1 && tm_Temp.tm_mday == tm_TempCopy.tm_mday && tm_Temp.tm_mon == tm_TempCopy.tm_mon && tm_Temp.tm_year == tm_TempCopy.tm_year);
}

bool cDate_t::setDate(const int& day,const int& month,const int& year) 
{
	if (!legalDate(day, month, year)) 
	{
		return false;
	}
	_day = day;
	_month = month;
	_year = year;
	return true;
}

bool cDate_t::setPrintFormat(const int &format) 
{
	if (format == 1 || format == 2 || format == 3) {
		_printFormat = format;
		return true;
	}
	return false;
}

const char* cDate_t::getMonthName() const 
{
		struct tm tm_Temp;
		fillStruct_tm(tm_Temp);
		return monthNames[tm_Temp.tm_mon];
}

const char* cDate_t::getDayName() const 
{
		struct tm tm_Temp;
		fillStruct_tm(tm_Temp);
		return dayofweek[tm_Temp.tm_wday];
}

ostream &operator<<(ostream&  os, const cDate_t &t)
{
	if (t.getPrintFormat() == 1) {
		std::string monthName(t.getMonthName());
		monthName.erase(3);
		return os << setfill('0') << setw(2) << t.getDay() << "/" << setw(3) << monthName.c_str() << "/" << setw(4) << t.getYear();
	}
	
	if (t.getPrintFormat() == 2) {
		return os << setfill('0') << setw(2) << t.getDay() << "/" << setw(2) << t.getMonth() << "/" << setw(4) << t.getYear();
	}
	
	return os << setfill('0') << setw(2) << t.getMonth() << "/" << setw(2) << t.getDay() << "/" << setw(4) << t.getYear();
}

cDate_t &cDate_t::operator=(const cDate_t &other){
	if (this != &other)
	{
		_day = other.getDay();
		_month = other.getMonth();
		_year = other.getYear();
	}
	return *this;
}

int cDate_t::getDay()const{
	return _day;
}
int cDate_t::getMonth() const{
	return _month;
}
int cDate_t::getYear() const{
	return _year;
}
